#include <iostream>
#include <vector>
#include<stack>
#include<algorithm>
using std::stack;
using std::max;
using std::string;
using std::vector;



class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        int m = matrix.size();
        int n = matrix[0].size();
        vector<vector<int>> width(n, vector<int>(m, 0));    // 按列存储，height[j, i]代表点[i, j]在i行右边连续的距离
        // width赋值
        
        for (int i = 0; i < m; i++) {
            
            for (int j = n-1; j >= 0; j --) {
                if (matrix[i][j] == '1') {
                    width[j][i] = (j == n-1) ? 0 : width[j+1][i];
                    width[j][i] += 1;
                }
            }
        }
        std::cout << "width: \n";
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                std::cout << width[j][i] << " ";
            }
            std::cout << "\n";
        }
        int maxArea = 0;
        for (int i = 0; i < n; i++) {
            maxArea = max(maxArea, largestRectangleArea(width[i]));
        }
        return maxArea;
    }

    int largestRectangleArea(vector<int>& heights) {
        vector<int> hs(heights.size(), 0);
        stack<int> sk;
        for (int i = 0; i < heights.size(); i++) {
            hs[i] = getWidth(sk, heights, i, true);
        }
        //for (auto h: hs) std::cout << h << " ";
        //std::cout << "\n";
        sk = {};
        // std::cout << "stack size: " << sk.size() << "\n";
        for (int i = heights.size()-1; i >= 0; i--) {
            auto h = getWidth(sk, heights, i, false);
            //std::cout << h << " ";
            hs[i] += h + 1;
        }
        //std::cout << "\n";
        int maxArea = 0;
        for (int i = 0; i < heights.size(); i++) {
            maxArea = max(maxArea, hs[i] * heights[i]);
        }
        return maxArea;

    }

    int getWidth(stack<int>& sk, vector<int>& heights, int idx, bool left) {
        while (!sk.empty() && (heights[sk.top()] >= heights[idx])) {
            sk.pop();
        }
        auto bound = left ? -1 : heights.size();
        if (!sk.empty()) bound = sk.top();
        sk.push(idx);
        return left ? idx - bound - 1: bound - idx - 1;

    }

};


int main() {
    int m, n;
    char tmp;
    std::cin >> m >> n;
    std::cout << "(" << m << ", " << n << ")\n";
    vector<vector<char>> input(m, vector<char>(n, 0));
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            std::cin >> tmp;
            input[i][j] = tmp;
            std::cout << input[i][j] << " ";

        }
        std::cout << "\n";
    }
    auto res = Solution().maximalRectangle(input);
    std::cout << "max rect area: " << res << "\n";
    return 0;
}